package org.eclipse.soc.ide4edu.assignment.operations;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;

public class AssignmentCreationOperation {

	private final String DETAILS_PATH = "Details";
	private final String EXTRAS_PATH = "Extras";
	private final String SOURCES_PATH = "Sources";
	private final String TESTS_PATH = "Tests";

	InputStream textMarkerStream;
	InputStream styleMarkerStream;
	InputStream nullStream;

	final String TEXTMARKER = "\n--TEXT--\n";
	final String STYLEMARKER = "\n--STYLE--\n";

	private IProject assignment;

	public AssignmentCreationOperation() {

	}

	public void createAssignment(IWorkspaceRoot root, String assignmentName,
			String assignmentPath, InputStream details, InputStream deadline,
			InputStream requirements, InputStream evaluation,
			String[] references, IProgressMonitor progress)
			throws CoreException {
		assignment = getAssignmentHandle(root, assignmentName, assignmentPath);
		createDirectoryStructure(assignment, progress);
		createFiles(assignment, details, deadline, requirements, evaluation,
				references, progress);

	}

	private void createAssignmentDescriptionFile(IProject assignment,
			InputStream requirements) throws CoreException {

		InputStream assignmentDescriptionContents = requirements;
		IPath assignmentDescriptionPath = new Path("//" + DETAILS_PATH + "//"
				+ "desc.asg");
		IFile assignmentDescriptionFile = assignment
				.getFile(assignmentDescriptionPath);
		assignmentDescriptionFile.create(assignmentDescriptionContents, true,
				null);

	}

	private void createAssignmentDetailsFile(IProject assignment,
			InputStream details, InputStream deadline) throws CoreException {

		InputStream contentsFromInitialPage = details;
		InputStream contentsFromDeadlinePage = deadline;

		IPath assignmentDetailsFilePath = new Path("//" + DETAILS_PATH + "//"
				+ "info.asg");
		IFile assignmentDetailsFile = assignment
				.getFile(assignmentDetailsFilePath);

		textMarkerStream = new ByteArrayInputStream(TEXTMARKER.getBytes());
		styleMarkerStream = new ByteArrayInputStream(STYLEMARKER.getBytes());
		nullStream = new ByteArrayInputStream(new String("null").getBytes());

		assignmentDetailsFile.create(textMarkerStream, true, null);
		assignmentDetailsFile.appendContents(contentsFromInitialPage, false,
				false, null);
		assignmentDetailsFile.appendContents(contentsFromDeadlinePage, false,
				false, null);

		textMarkerStream = new ByteArrayInputStream(TEXTMARKER.getBytes());

		assignmentDetailsFile.appendContents(textMarkerStream, false, false,
				null);

		assignmentDetailsFile.appendContents(styleMarkerStream, false, false,
				null);

		assignmentDetailsFile.appendContents(nullStream, false, false, null);

		styleMarkerStream = new ByteArrayInputStream(STYLEMARKER.getBytes());

		assignmentDetailsFile.appendContents(styleMarkerStream, false, false,
				null);

	}

	private void createAssignmentEvaluationFile(IProject assignment,
			InputStream evaluation) throws CoreException {
		InputStream assignmentEvaluationContents = evaluation;
		IPath assignmentEvaluationPath = new Path("//" + DETAILS_PATH + "//"
				+ "eval.asg");
		IFile assignmentEvaluationFile = assignment
				.getFile(assignmentEvaluationPath);
		assignmentEvaluationFile.create(assignmentEvaluationContents, true,
				null);
	}

	private void createDirectoryStructure(IProject assignment,
			IProgressMonitor progress) throws CoreException {

		IPath extrasPath = new Path(EXTRAS_PATH);
		IPath detailsPath = new Path(DETAILS_PATH);
		IPath sourcesPath = new Path(SOURCES_PATH);
		IPath testsPath = new Path(TESTS_PATH);

		IFolder extrasFolder = assignment.getFolder(extrasPath);
		IFolder detailsFolder = assignment.getFolder(detailsPath);
		IFolder sourcesFolder = assignment.getFolder(sourcesPath);
		IFolder testsFolder = assignment.getFolder(testsPath);

		progress.setTaskName("Creating extras ...");
		extrasFolder.create(true, true, progress);
		progress.worked(10);
		progress.setTaskName("Creating details ...");
		detailsFolder.create(true, true, progress);
		progress.worked(10);
		progress.setTaskName("Creating sources ...");
		sourcesFolder.create(true, true, progress);
		progress.worked(10);
		progress.setTaskName("Creating tests ...");
		testsFolder.create(true, true, progress);
		progress.worked(10);
	}

	private void createFiles(IProject assignment, InputStream details,
			InputStream deadline, InputStream requirements,
			InputStream evaluation, String[] references,
			IProgressMonitor progress) throws CoreException {
		progress.setTaskName("Creating Details File ...");
		createAssignmentDetailsFile(assignment, details, deadline);
		progress.worked(10);
		progress.setTaskName("Creating Functional Requirements ...");
		createAssignmentDescriptionFile(assignment, requirements);
		progress.worked(10);
		progress.setTaskName("Creating Evaluation Criteria...");
		createAssignmentEvaluationFile(assignment, evaluation);
		progress.worked(10);
		progress.setTaskName("Creating References ...");
		createReferenceFile(assignment, references);
		progress.worked(10);
	}

	private void createReferenceFile(IProject assignment, String[] reference)
			throws CoreException {

		IPath referencePath = new Path("//" + DETAILS_PATH + "//" + "refer.asg");
		IFile referenceFile = assignment.getFile(referencePath);
		String references[] = reference;
		String contents = new String("References\n");
		for (int i = 0; i < 5; i++) {
			if (references[i] != null)
				contents += "[" + (i + 1) + "] " + references[i] + "\n";
		}

		if (contents == "References\n")
			contents = "No Reference Books or Links Specified!";

		InputStream referenceStream = new ByteArrayInputStream(contents
				.getBytes());

		textMarkerStream = new ByteArrayInputStream(TEXTMARKER.getBytes());
		styleMarkerStream = new ByteArrayInputStream(STYLEMARKER.getBytes());
		nullStream = new ByteArrayInputStream(new String("null").getBytes());

		referenceFile.create(textMarkerStream, true, null);

		referenceFile.appendContents(referenceStream, true, false, null);

		textMarkerStream = new ByteArrayInputStream(TEXTMARKER.getBytes());

		referenceFile.appendContents(textMarkerStream, true, false, null);
		referenceFile.appendContents(styleMarkerStream, true, false, null);
		referenceFile.appendContents(nullStream, true, false, null);

		styleMarkerStream = new ByteArrayInputStream(STYLEMARKER.getBytes());
		referenceFile.appendContents(styleMarkerStream, true, false, null);

	}

	private IProject getAssignmentHandle(IWorkspaceRoot root,
			String assignmentName, String location) throws CoreException {
		IProject assignment = root.getProject(assignmentName);

		assignment.create(null);
		assignment.open(new NullProgressMonitor());

		IProjectDescription description = assignment.getDescription();
		description.setComment("IDE4EDU Assignment");
		assignment.setDescription(description, null);

		return assignment;
	}

}
